package com.imooc.coupon.service.impl;

import com.imooc.coupon.exception.CouponException;
import com.imooc.coupon.support.vo.CouponTemplateSDK;
import com.imooc.coupon.entity.CouponTemplate;
import com.imooc.coupon.repository.CouponTemplateRepo;
import com.imooc.coupon.service.TemplateBaseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 优惠券模板基础服务接口实现
 * Created By TINY
 * Create Time 2020/2/10
 **/
@Service
@Slf4j
public class TemplateBaseServiceImpl implements TemplateBaseService {

    /** 优惠券模板数据持久层对象 */
    private final CouponTemplateRepo templateRepo;

    @Autowired
    public TemplateBaseServiceImpl(CouponTemplateRepo templateRepo) {
        this.templateRepo = templateRepo;
    }

    /**
     * 根据优惠券模板 id 构建优惠券模板信息
     *
     * @param id 模板id
     * @return {@link CouponTemplate} 模板实体
     * @throws CouponException 系统业务异常
     */
    @Override
    public CouponTemplate buildTemplateInfo(Integer id) throws CouponException {

        // 根据 id 查找优惠券模板
        Optional<CouponTemplate> template = templateRepo.findById(id);
        if (!template.isPresent()) {
            throw new CouponException("优惠券模板不存在！");
        }

        return template.get();
    }

    /**
     * 查找所有可用的优惠券模板
     *
     * @return {@link CouponTemplateSDK} 优惠券模板集合
     */
    @Override
    public List<CouponTemplateSDK> findAllUsableTemplate() {

        // 根据模板可用并且未过期等条件查询所有模板；由于优惠券的过期设置是由定时任务处理的，
        // 所以这里返回的结果并非是完全可信的
        List<CouponTemplate> templates = templateRepo
                .findAllByAvailableAndExpired(true, false);

        // 将所有的 CouponTemplate 转化为 CouponTemplateSDK 并收集为 List 返回
        return templates.stream()
                .map(this::template2TemplateSDK).collect(Collectors.toList());
    }

    /**
     * 找到所有与ids中对应的优惠券模板的集合，以Map形式返回
     *
     * @param ids 目标优惠券id集合
     * @return 符合条件的优惠券模板
     */
    @Override
    public Map<Integer, CouponTemplateSDK> findIds2TemplateSDK(
            Collection<Integer> ids) {

        // 根据 ids 查找所有的优惠券模板
        List<CouponTemplate> templates = templateRepo.findAllById(ids);

        // 将所有的优惠券模板转化为 CouponTemplateSDK 后收集为 Map 类型返回
        return templates.stream().map(this::template2TemplateSDK)
                .collect(Collectors.toMap(
                        CouponTemplateSDK::getId, // 将CouponTemplateSDK中的id作为键
                        Function.identity()       // 将CouponTemplateSDK本身作为值
                ));
    }

    /**
     * 将 CouponTemplate 转换为 CouponTemplateSDK
     * @param template {@link CouponTemplate} 优惠券模板实体
     * @return {@link CouponTemplateSDK} 优惠券模板值对象
     */
    private CouponTemplateSDK template2TemplateSDK(CouponTemplate template) {

        return new CouponTemplateSDK(
                template.getId(),
                template.getName(),
                template.getLogo(),
                template.getDesc(),
                template.getCategory().getCode(),
                template.getProductLine().getCode(),
                template.getKey(), // 这里的 key 还不是一个完整的 key，需要后续拼装
                template.getTarget().getCode(),
                template.getRule()
        );
    }
}
